package example;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * Created by IntelliJ IDEA.
 * User: stermi
 * Date: 29-nov-2009
 * Time: 11.34.41
 * To change this template use File | Settings | File Templates.
 */
public class Utente {

	/* TODO: aggiungere restrizioni per < 14 o < 18? ---> aggiungerli anche a visualizzazione Film */
	
	public static final String tabName = "utente";

    public static final String idField = "id";
    public static final String codiceCartaField = "codice_carta";
    public static final String nomeField = "nome";
    public static final String cognomeField = "cognome";
    public static final String compleannoField = "compleanno";
    public static final String emailField = "email";
    public static final String passwordField = "password";
    public static final String codiceFiscaleField = "codice_fiscale";
    public static final String cittaField = "citta";
    public static final String viaField = "via";
    public static final String recapitoTelefonicoField = "recapito_telefonico";
    public static final String roleIdField = "role_id";
	
    int id;
    String codiceCarta; /* come e' fatto il codice della carta? tipo 5num+5lett+10num+5lett */
    
    String nome;
    String cognome;
    Date compleanno;
    
    String email;
    String password;
    String codiceFiscale;
    
    String citta;
    String via;
    String recapitoTelefonico;
    
    int roleId; /* 0 utente, 1 magazzino */

    public Utente( ) {
    	this.id = -1;
    	this.codiceCarta = "";        
    }
    
    public Result validate() {
    	Result result = new Result( true, null, "" );
    	Result resultCF = null;
    	
    	if ( nome.trim().equals("") ) { 
    		result.result = false;
    		result.errorMessage += "Il nome non puo' essere vuoto\n";
    	}
    	
    	if ( cognome.trim().equals("") ) { 
    		result.result = false;
    		result.errorMessage += "Il cognome non puo' essere vuoto\n";
    	}
    	
    	if ( password.trim().equals("") ) { 
    		result.result = false;
    		result.errorMessage += "La password non puo' essere vuota\n";
    	}
    	
    	if ( codiceCarta.trim().equals("") ) {  /* TODO aggiungere regex che controlla codicecarta */
    		result.result = false;
    		result.errorMessage += "Il codice carta non puo' essere vuoto\n";
    	}
    	
    	if ( email.trim().equals("") ) { 
    		result.result = false;
    		result.errorMessage += "L'email non puo' essere vuota\n";
    	}
    	
    	if ( ! Utils.checkEmail( email ) ) {
    		result.result = false;
    		result.errorMessage += "L'email non e' nel formato valido\n";
    	}
    	
    	if ( codiceFiscale.trim().equals("") ) { 
    		result.result = false;
    		result.errorMessage += "Il codiceFiscale non puo' essere vuoto\n";
    	}
    	
    	resultCF = Utils.checkCF( codiceFiscale );
    	
    	if ( !resultCF.result ) { 
    		result.result = false;
    		result.errorMessage += resultCF.errorMessage + "\n";
    	}
    	
    	
    	return result;
    }

    public Result load( int id, Connection c ) {
    	// load it from DB
    	Result result; 	
    	PreparedStatement pstmt = null;
        ResultSet rs = null;
        String sqlQuery = "SELECT * FROM " + tabName + " WHERE "+ idField + " = ?";
        
        try {
        	c.setAutoCommit(false);
        	pstmt = c.prepareStatement(sqlQuery);
        	pstmt.setInt(1, id  );
	        rs = pstmt.executeQuery();
	        
	        if ( rs.next() ) {
	        	this.set( rs );
	        	result = new Result( true, this, "Utente " + this.nome + " " + this.cognome + " caricato con successo");
	        	
	        } else {
	        	//errore, non c'era il record sul db
	        	System.out.println("L'utente con id " + this.id + " non e' presente sul database.");
	        	result = new Result( false, null, "");
	        }
	        
	        rs.close();
	        pstmt.close();
	        c.commit();
	        
	        
        } catch (SQLException e) {
        	System.out.println( "SQL Exception: " +e.getMessage());
            result = new Result(false, null,  "SQL Exception: " +e.getMessage() + " per utente con ID " + this.id );
        } finally {
            try{
                if( rs != null )
                    rs.close();
                if( pstmt != null )
                    pstmt.close();
            } catch(Exception e){
            	result = new Result ( false, null, "Rilascio risorse non riuscito: " +e.getMessage() + "\nRecord non caricato con utente ID " + this.id );
                System.out.println("Rilascio risorse non riuscito: "+e.getMessage());
            }
        }
        
        return result;
    }

    
    private void set ( ResultSet rs ) throws SQLException {
    	this.id = rs.getInt( idField );
    	this.codiceCarta = rs.getString( codiceCartaField );
    	this.nome = rs.getString( nomeField );
    	this.cognome = rs.getString( cognomeField );
    	this.compleanno = rs.getDate( compleannoField );
    	this.email = rs.getString( emailField );
    	this.password = rs.getString( passwordField );
    	this.codiceFiscale = rs.getString( codiceFiscaleField );
    	this.citta = rs.getString( cittaField );
    	this.via = rs.getString( viaField );
    	this.recapitoTelefonico = rs.getString( recapitoTelefonicoField );
    	this.roleId = rs.getInt( roleIdField );
    }
    
    public void set ( Utente o ) {
    	this.id = o.id;
    	this.codiceCarta = o.codiceCarta;
    	this.nome = o.nome;
    	this.cognome = o.cognome;
    	this.compleanno = o.compleanno;
    	this.email = o.email;
    	this.password = o.password;
    	this.codiceFiscale = o.codiceFiscale;
    	this.citta = o.citta;
    	this.via = o.via;
    	this.recapitoTelefonico = o.recapitoTelefonico;
    	this.roleId = o.roleId;
    }
    
    public Result save( Connection c ) {
    	return save( c, true );
    }

    public Result save( Connection c, boolean validate ) {
    	
    	Result result = null;
    	int rowAffected;
    	boolean insert;
    	
    	String query = "";
    	PreparedStatement pstmt = null;
    	ResultSet rs = null;
    	
    	if ( validate ) {
    		result = validate();
    		if ( !result.result )
    			return result;
    	}
    	
    	try {
    		
    		c.setAutoCommit(false);

    		if ( this.id < 1 ) { //non e' un nuovo record
    			query = "INSERT INTO "+ tabName +" ( " + idField + ", " + codiceCartaField + ", " + nomeField + ", " + cognomeField + ", " + compleannoField + ", " + emailField + ", " + passwordField + ", " + codiceFiscaleField + ", " + cittaField + ", " + viaField + ", " + recapitoTelefonicoField + ", " + roleIdField + "  ) VALUES (DEFAULT,?,?,?,?,?,?,?,?,?,?,?)";
	    		insert = true;
	    		pstmt = c.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
	    		
	    		
	    	} else {
	    		c.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
	    		query = "UPDATE "+ tabName +" SET " + codiceCartaField + " = ?, " + nomeField + " = ?, " + cognomeField + " = ?, " + compleannoField + " = ?, " + emailField + " = ?, " + passwordField + " = ?, " + codiceFiscaleField + " = ?, " + cittaField + " = ?, " + viaField +  " = ?, " + recapitoTelefonicoField +  " = ?, " + roleIdField + " = ? WHERE " + idField + " = ?";
	    		insert = false;
	    		pstmt = c.prepareStatement(query);
	    	}
	    	
	    	
	    	pstmt.setString(1, this.codiceFiscale );
	    	pstmt.setString(2, this.nome  );
	    	pstmt.setString(3, this.cognome  );
	    	pstmt.setDate(4, this.compleanno  );
	    	pstmt.setString(5, this.email  );
	    	pstmt.setString(6, this.password  );
	    	pstmt.setString(7, this.codiceFiscale  );
	    	pstmt.setString(8, this.citta  );
	    	pstmt.setString(9, this.via  );
	    	pstmt.setString(10, this.recapitoTelefonico  );
	    	pstmt.setInt(11, this.roleId  );
	    	
	    	if ( this.id > 0 )
	    		pstmt.setInt(12, this.id  );
	    	
	    	rowAffected = pstmt.executeUpdate();
	    	
	    	if ( rowAffected > 0 ) {
	    		result = new Result(true, this, "Operazione di " + ( insert ? " insert" : "update" ) + " avvenuta con successo per utente " + this.nome + " " + this.cognome +  " con ID " + this.id );
	    		
	    	} else {
	    		result = new Result(false, null, "Errore durante operazione di " + ( insert ? " insert" : "update" ) + " per utente " + this.nome + " " + this.cognome +  " con ID " + this.id );
	    		if ( Test.DEBUG ) System.out.println( result.errorMessage );
	    	}
	    	
	    	
	    	//Aggiorno l'id del film	    	
	    	if ( rowAffected > 0 && insert ) {
	    		rs = pstmt.getGeneratedKeys();
	    		
	    		
	    		// TODO capire perche' cazzo non va GET ID
	    		if ( rs != null && rs.next() ) {
	    			this.id = rs.getInt(1);
		    		result = new Result(true, this, "Operazione di insert avvenuta con successo per utente " + this.nome + " " + this.cognome +  " con ID " + this.id );
		    		if ( Test.DEBUG ) System.out.println( result.errorMessage );
	    		}
	    		rs.close();	
	    	}
	    	
	    	pstmt.close();
	    	c.commit();
	    	
	    	c.setAutoCommit(true);
	    	
	    	
	    	
    	} catch(Exception e){
    		result = new Result ( false, null, "Errore generale: " +e.getMessage() + "\nRecord non inserito per utente " + this.nome + " " + this.cognome +  " con ID " + this.id );
    		if ( Test.DEBUG ) System.out.println( result.errorMessage );
            // rollback
            try{
            	System.out.println("Rollback, annullo modifiche al database");
                c.rollback();
            } catch(Exception eRollback){}
        
        } finally {
            try{
                if( rs != null )
                    rs.close();
                if( pstmt != null )
                    pstmt.close();
            } catch(Exception e){
            	result = new Result ( false, null, "Rilascio risorse non riuscito: "+e.getMessage() + "\nRecord non inserito per utente " + this.nome + " " + this.cognome +  " con ID " + this.id );
            	System.out.println( result.errorMessage );
            }
        }
        return result;
    }

    public Result delete( Connection c ) {
    	
    	String query = "";
    	PreparedStatement pstmt = null;
    	Result result = null;
    	int affectedRows = 0;
    	
    	try {
    		c.setAutoCommit(false);
    		query = "DELETE FROM " + tabName + " WHERE " + idField + " = ?";
    		pstmt = c.prepareStatement(query);
    		pstmt.setInt(1, this.id);
    		
    		affectedRows = pstmt.executeUpdate();
    		if ( affectedRows > 0 ) {
    			result = new Result ( true, null, "Record cancellato con utente " + this.nome + " " + this.cognome +  " con ID " + this.id );
	    	} else {
	    		result = new Result ( false, null, "Record NON cancellato con utente " + this.nome + " " + this.cognome +  " con ID " + this.id );
	    	}
    			
    		pstmt.close();
    		c.commit();

    		
    	} catch(Exception e){
            result = new Result ( false, null, "Errore generale: " +e.getMessage() + "\nRecord non cancellato con utente " + this.nome + " " + this.cognome +  " con ID " + this.id );
            if ( Test.DEBUG ) System.out.println( result.errorMessage );
            // rollback
            try{
            	System.out.println("Rollback, annullo modifiche al database");
                c.rollback();
            } catch(Exception eRollback){}
        
        } finally {
            try{
                if( pstmt != null )
                    pstmt.close();
            } catch(Exception e){
            	result = new Result ( false, null, "Rilascio risorse non riuscito: " +e.getMessage() + "\nRecord non cancellato con utente " + this.nome + " " + this.cognome +  " con ID " + this.id );
                System.out.println("Rilascio risorse non riuscito: "+e.getMessage());
            }
        }
        
        
    	return result;
    }

    public String toString() {
    	
        String ret = "";
        
        ret += "[" + this.id + "] " + this.nome + " " + this.cognome + "\n";
        ret += "--- codiceCarta: " + this.codiceCarta + "\n";
        ret += "--- codiceFiscale: " + this.codiceFiscale + "\n";
        ret += "--- Compleanno: " + this.compleanno + "\n";
        ret += "--- Email: " + this.email + "\n";
        ret += "--- password: " + this.password + "\n";
        ret += "--- citta: " + this.citta + "\n";
        ret += "--- via: " + this.via + "\n";
        ret += "--- recapito: " + this.recapitoTelefonico + "\n";
        
        return ret;
    }

}
